package com.thiny.android.game.thunderbolt.view;

import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Vibrator;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.thiny.android.game.thunderbolt.R;
import com.thiny.android.game.thunderbolt.callback.BeFiredCallback;
import com.thiny.android.game.thunderbolt.callback.KillBossCallBack;
import com.thiny.android.game.thunderbolt.role.BaseRole;
import com.thiny.android.game.thunderbolt.role.Bullet;
import com.thiny.android.game.thunderbolt.role.Enemy;
import com.thiny.android.game.thunderbolt.role.Explode;
import com.thiny.android.game.thunderbolt.role.Player;
import com.thiny.android.game.thunderbolt.role.Property;
import com.thiny.android.game.thunderbolt.thread.ControlThread;
import com.thiny.android.game.thunderbolt.thread.GameViewThread;
import com.thiny.android.game.thunderbolt.ui.GameActivity;
import com.thiny.android.game.thunderbolt.ui.ReportScoreActivity;
import com.thiny.android.game.thunderbolt.util.Constants;
import com.thiny.android.game.thunderbolt.util.SoundManager;
import com.thiny.android.game.thunderbolt.util.Utils;

public class GameView extends SurfaceView implements SurfaceHolder.Callback,
		KillBossCallBack, BeFiredCallback {

	private GameActivity mGameActivity;
	// 振动器，我方被击中时候调用
	private Vibrator vibrator;
	private int mScreenWidth, mScreenHeight;
	// 关卡
	private int mLevel;
	// 播放动画使用，获取对应动画帧
	private int animationNum;
	// 刷新动画帧时候使用
	private int animationCount;

	private SurfaceHolder mSurfaceHolder;
	private Paint mPaint;

	private Player mPlayer;
	// 我方战机是否开火
	private boolean isFire;
	// boss是否被杀
	private boolean isBossKilled;
	// 是否启动动画播放
	private boolean startAnimation;
	// 我方飞机发出的子弹list
	ArrayList<Bullet> mPlayerBullets = new ArrayList<Bullet>();
	// 敌方飞机发出的子弹list
	ArrayList<Bullet> mEnemyBullets = new ArrayList<Bullet>();
	// 敌方的飞机list
	ArrayList<Enemy> mEnemies = new ArrayList<Enemy>();
	// 爆炸list
	ArrayList<Explode> mExplodes = new ArrayList<Explode>();
	// 道具list
	ArrayList<Property> mProperties = new ArrayList<Property>();

	// 游戏刷新线程
	private GameViewThread mGameViewThread;

	// 游戏控制线程，包括角色的移动，射击等
	private ControlThread mControlThread;

	public Bitmap[] enemyExplodeBmps;
	public Bitmap[] bulletExplodeBmps;
	public Bitmap[] lifeBmps;
	public Bitmap[] animationBmps;

	// 各个角色的bitmap
	public Bitmap player1;
	public Bitmap player2;
	public Bitmap player3;

	public Bitmap enemy1;
	public Bitmap enemy2;
	public Bitmap enemy3;
	public Bitmap enemy4;
	public Bitmap enemy_boss1;
	public Bitmap enemy_boss2;
	public Bitmap enemy_boss3;

	public Bitmap playerBullet1;
	public Bitmap playerBullet2;

	public Bitmap enemyBullet1;
	public Bitmap enemyBullet2;
	public Bitmap enemyBullet3;

	// 道具系列
	public Bitmap addLife;
	public Bitmap addBullet;
	public Bitmap changeBullet;
	public Bitmap speedUp;
	public Bitmap clearAllEnemy;

	// 背景bitmap
	public Bitmap backgroundBitmap;
	// 背景坐标
	public float backgroundY;
	// 背景分数
	public long score;
	// 随机数
	public Random mRandom;

	// 敌机爆炸的所有帧
	private static final int[] enemyExplodesID = new int[] {
			R.drawable.enemy_explode1, R.drawable.enemy_explode2,
			R.drawable.enemy_explode3, R.drawable.enemy_explode4,
			R.drawable.enemy_explode5, R.drawable.enemy_explode6 };

	// 子弹爆炸的所有帧
	private static final int[] bulletExplodesID = new int[] {
			R.drawable.bullet_explode00, R.drawable.bullet_explode01,
			R.drawable.bullet_explode02, R.drawable.bullet_explode03,
			R.drawable.bullet_explode04, R.drawable.bullet_explode05,
			R.drawable.bullet_explode06, R.drawable.bullet_explode07,
			R.drawable.bullet_explode08 };

	// 动画所有帧
	private static final int[] animationID = new int[] {
			R.drawable.clear_anim_00, R.drawable.clear_anim_01,
			R.drawable.clear_anim_02, R.drawable.clear_anim_03,
			R.drawable.clear_anim_04, R.drawable.clear_anim_05,
			R.drawable.clear_anim_06, R.drawable.clear_anim_07,
			R.drawable.clear_anim_08, R.drawable.clear_anim_09,
			R.drawable.clear_anim_10, R.drawable.clear_anim_11,
			R.drawable.clear_anim_12, R.drawable.clear_anim_13,
			R.drawable.clear_anim_14, R.drawable.clear_anim_15,
			R.drawable.clear_anim_16, R.drawable.clear_anim_17,
			R.drawable.clear_anim_18, R.drawable.clear_anim_19,
			R.drawable.clear_anim_20, R.drawable.clear_anim_21,
			R.drawable.clear_anim_22, R.drawable.clear_anim_23,
			R.drawable.clear_anim_24, R.drawable.clear_anim_25,
			R.drawable.clear_anim_26, R.drawable.clear_anim_27,
			R.drawable.clear_anim_28, R.drawable.clear_anim_29,
			R.drawable.clear_anim_30 };

	// 生命图片资源
	private static final int[] livesID = new int[] { R.drawable.life1,
			R.drawable.life2, R.drawable.life3, R.drawable.life4,
			R.drawable.life5, R.drawable.life6 };

	public GameView(GameActivity gameActivity, int level) {
		super(gameActivity);
		mGameActivity = gameActivity;
		mScreenWidth = Utils.getScreenWidth(gameActivity);
		mScreenHeight = Utils.getScreenHeight(gameActivity);
		mLevel = level;
		vibrator = (Vibrator) getContext().getSystemService(
				Service.VIBRATOR_SERVICE);
		init();
	}

	// 初始化各种资源bitmap
	private void initBitmap() {

		// 初始化我方战机bitmap
		player1 = BitmapFactory.decodeResource(getResources(),
				R.drawable.player1);
		player2 = BitmapFactory.decodeResource(getResources(),
				R.drawable.player2);
		player3 = BitmapFactory.decodeResource(getResources(),
				R.drawable.player3);

		// 初始化敌人bitmap
		enemy1 = BitmapFactory
				.decodeResource(getResources(), R.drawable.enemy1);
		enemy2 = BitmapFactory
				.decodeResource(getResources(), R.drawable.enemy2);
		enemy3 = BitmapFactory
				.decodeResource(getResources(), R.drawable.enemy3);
		enemy4 = BitmapFactory
				.decodeResource(getResources(), R.drawable.enemy4);
		enemy_boss1 = BitmapFactory.decodeResource(getResources(),
				R.drawable.boss1);
		enemy_boss2 = BitmapFactory.decodeResource(getResources(),
				R.drawable.boss2);
		enemy_boss3 = BitmapFactory.decodeResource(getResources(),
				R.drawable.boss3);

		// 初始化子弹bitmap
		playerBullet1 = BitmapFactory.decodeResource(getResources(),
				R.drawable.player_bullet1);
		playerBullet2 = BitmapFactory.decodeResource(getResources(),
				R.drawable.player_bullet2);
		enemyBullet1 = BitmapFactory.decodeResource(getResources(),
				R.drawable.enemy_bullet1);
		enemyBullet2 = BitmapFactory.decodeResource(getResources(),
				R.drawable.enemy_bullet2);
		enemyBullet3 = BitmapFactory.decodeResource(getResources(),
				R.drawable.enemy_bullet3);

		backgroundBitmap = BitmapFactory.decodeResource(getResources(),
				R.drawable.background);

		// 初始化敌机爆炸图片，避免在构造对象时候多次初始化
		enemyExplodeBmps = new Bitmap[enemyExplodesID.length];
		for (int i = 0; i < enemyExplodeBmps.length; i++) {
			enemyExplodeBmps[i] = BitmapFactory.decodeResource(getResources(),
					enemyExplodesID[i]);
		}

		// 初始化子弹爆炸图片，避免在构造对象时候多次初始化
		bulletExplodeBmps = new Bitmap[bulletExplodesID.length];
		for (int i = 0; i < bulletExplodeBmps.length; i++) {
			bulletExplodeBmps[i] = BitmapFactory.decodeResource(getResources(),
					bulletExplodesID[i]);
		}

		// 初始化生命数目图片
		lifeBmps = new Bitmap[livesID.length];
		for (int i = 0; i < lifeBmps.length; i++) {
			lifeBmps[i] = BitmapFactory.decodeResource(getResources(),
					livesID[i]);
		}

		// 初始化动画图片
		animationBmps = new Bitmap[animationID.length];
		for (int i = 0; i < animationID.length; i++) {
			animationBmps[i] = BitmapFactory.decodeResource(getResources(),
					animationID[i]);
		}
		addLife = BitmapFactory.decodeResource(getResources(),
				R.drawable.prop_add_life);
		addBullet = BitmapFactory.decodeResource(getResources(),
				R.drawable.prop_add_bullet);
		changeBullet = BitmapFactory.decodeResource(getResources(),
				R.drawable.prop_change_bullet);
		speedUp = BitmapFactory.decodeResource(getResources(),
				R.drawable.prop_speed_up);
		clearAllEnemy = BitmapFactory.decodeResource(getResources(),
				R.drawable.prop_clear_all);

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {

		mGameViewThread = new GameViewThread(this);
		mControlThread = new ControlThread(this);
		mControlThread.setKillBossCallBack(this);
		mControlThread.setBeFiredCallback(this);
		mGameViewThread.start();
		mControlThread.start();

	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		mGameViewThread.setFlag(false);
		mControlThread.setFlag(false);
		mControlThread.setKillBossCallBack(null);
		mControlThread.setBeFiredCallback(null);
		mControlThread.isInterrupted();
		mGameViewThread.isInterrupted();
	}

	// 设置线程循环开关，应用退出时候要设置关闭，否则报错
	public void setFlag(boolean flag) {
		mGameViewThread.setFlag(flag);
		mControlThread.setFlag(flag);
	}

	public Player getPlayer() {
		return mPlayer;
	}

	// 设置玩家是否可射击
	public void setFire(boolean isFire) {
		this.isFire = isFire;
	}

	public boolean isFire() {
		return isFire && mPlayer.isAlive();
	}

	// 获取道具list
	public synchronized ArrayList<Property> getProperties() {
		return mProperties;
	}

	// 获取爆炸list
	public synchronized ArrayList<Explode> getExplodes() {
		return mExplodes;
	}

	// 添加爆炸
	public void addExplode(Explode explode) {
		mExplodes.add(explode);
	}

	// 移除爆炸
	public void removeExplode(Explode explode) {
		mExplodes.remove(explode);
	}

	// 获取敌人子弹list
	public synchronized ArrayList<Bullet> getEnemyBullets() {
		return mEnemyBullets;
	}

	// 获取玩家飞机子弹list
	public synchronized ArrayList<Bullet> getPlayerBullets() {
		return mPlayerBullets;
	}

	// 获取敌人list
	public synchronized ArrayList<Enemy> getEnemies() {
		return mEnemies;
	}

	// 获取手机屏幕宽度
	public int getScreenWidth() {
		return mScreenWidth;
	}

	// 获取手机屏幕长度
	public int getScreenHeight() {
		return mScreenHeight;
	}

	// 初始化所有游戏数据
	private void init() {
		mSurfaceHolder = getHolder();
		mSurfaceHolder.addCallback(this);

		mPaint = new Paint();
		mPaint.setTextSize(50);
		mPaint.setColor(Color.WHITE);
		initBitmap();

		mPlayer = new Player(this, (mScreenWidth - player1.getWidth()) / 2,
				(mScreenHeight - player1.getHeight()) / 2,
				Constants.PLAYER_TYPE_1, Constants.PLAYER_BULLET_SPEED,
				Constants.LIFE_PLAYER);
		mRandom = new Random();
	}

	// 封装用于画游戏页面的方法，在线程GameViewThread中调用
	public void draw() {
		Canvas canvas = mSurfaceHolder.lockCanvas();
		if (canvas == null) {
			return;
		}

		mPaint.setTextSize(30);
		canvas.drawBitmap(backgroundBitmap, 0, backgroundY, mPaint);
		canvas.drawBitmap(backgroundBitmap, 0,
				backgroundY - backgroundBitmap.getHeight(), mPaint);

		drawPlayerBullets(canvas);
		drawEnemies(canvas);

		// 画该战机的子弹
		drawEnemyBullets(canvas);

		if (mProperties.isEmpty() == false) {
			drawProperty(canvas);
		}

		if (mExplodes.isEmpty() == false) {
			drawExplode(canvas);
		}

		if (mPlayer.isAlive()) {
			mPlayer.draw(canvas);
		} else {
			drawGameWord(canvas, "游戏结束");
		}

		if (isBossKilled) {
			switch (mLevel) {
			case Constants.LEVEL_1:
				drawGameWord(canvas, "第一关");
				break;
			case Constants.LEVEL_2:
				drawGameWord(canvas, "第二关");
				break;
			case Constants.LEVEL_3:
				drawGameWord(canvas, "第三关");
				break;
			default:
				drawGameWord(canvas, "游戏胜利");
				break;
			}

		}

		drawScore(canvas);
		drawLife(canvas);

		if (startAnimation) {
			mControlThread.isOnPause = true;
			mPlayer.setAlive(false);
			drawAnimation(canvas, animationBmps[animationNum]);

			if (++animationCount == 3) {
				animationCount = 0;
				if (++animationNum >= animationID.length) {
					animationNum = 0;
					startAnimation = false;
					mControlThread.isOnPause = false;
					mPlayer.setAlive(true);
				}
			}
		}

		mSurfaceHolder.unlockCanvasAndPost(canvas);
	}

	// 画我方战机的子弹
	private void drawPlayerBullets(Canvas canvas) {

		Bullet bullet = null;
		synchronized (mPlayerBullets) {
			// 遍历，画出子弹
			for (int i = 0; i < mPlayerBullets.size(); i++) {
				bullet = mPlayerBullets.get(i);
				if (bullet == null) {
					continue;
				}
				bullet.draw(canvas);
				bullet = null;
			}
		}

	}

	// 画敌方战机
	private void drawEnemies(Canvas canvas) {
		// 遍历，画出敌机
		Enemy enemy = null;
		synchronized (mEnemies) {
			for (int i = 0; i < mEnemies.size(); i++) {
				enemy = mEnemies.get(i);
				if (enemy == null) {
					continue;
				}
				enemy.draw(canvas);
				enemy = null;
			}
		}

	}

	// 画敌方战机的子弹
	private void drawEnemyBullets(Canvas canvas) {

		Bullet bullet = null;
		synchronized (mEnemyBullets) {
			// 遍历，画出子弹
			for (int i = 0; i < mEnemyBullets.size(); i++) {
				bullet = mEnemyBullets.get(i);
				if (bullet == null) {
					continue;
				}
				bullet.draw(canvas);
				bullet = null;
			}
		}
	}

	// 画爆炸
	private void drawExplode(Canvas canvas) {

		Explode explode = null;

		// 遍历，画出所有爆炸
		for (int i = 0; i < mExplodes.size(); i++) {
			explode = mExplodes.get(i);
			if (explode == null) {
				break;
			}

			if (explode.nextFrame()) {
				explode.draw(canvas);
			}
			explode = null;
		}

	}

	// 画宝物
	private void drawProperty(Canvas canvas) {
		synchronized (mProperties) {
			Property property = null;
			for (int i = 0; i < mProperties.size(); i++) {
				property = mProperties.get(i);
				if (property == null) {
					break;
				}
				property.draw(canvas);
				property = null;
			}
		}
	}

	// 画分数
	private void drawScore(Canvas canvas) {
		canvas.drawText("" + score, mScreenWidth / 2, 30, mPaint);
	}

	// 画战机生命
	private void drawLife(Canvas canvas) {
		if (mPlayer.life - 1 < 0) {
			return;
		}
		canvas.drawBitmap(lifeBmps[mPlayer.life - 1], mScreenWidth
				- lifeBmps[mPlayer.life - 1].getWidth(), 0, mPaint);
	}

	// 画游戏胜利或者结束
	private void drawGameWord(Canvas canvas, String string) {
		Paint paint = new Paint();
		paint.setTextSize(50);
		paint.setColor(Color.WHITE);
		canvas.drawText(string, (mScreenWidth - 50 * string.length()) / 2, 250,
				paint);
	}

	/**
	 * 增加敌方战机 在moveThread中调用
	 */
	public void addEnemy() {
		int type = Constants.ENEMY_TYPE_1;
		switch (mRandom.nextInt(4)) {
		case 0:
			type = Constants.ENEMY_TYPE_2;
			break;
		case 1:
			if (mLevel > Constants.LEVEL_1) {
				type = Constants.ENEMY_TYPE_3;
			}
			break;
		case 2:
			if (mLevel > Constants.LEVEL_2) {
				type = Constants.ENEMY_TYPE_4;
			}
			break;

		}
		mEnemies.add(new Enemy(this, mRandom.nextFloat() * mScreenWidth, 0,
				type, Constants.ENEMY_SPEED, Constants.LIFE_ENEMY, mPlayer));
	}

	/**
	 * 增加BOSS 在moveThread中调用
	 */
	public void addBoss() {
		int type = Constants.ENEMY_TYPE_BOSS1;
		int life = Constants.LIFE_BOSS1;
		Bitmap bitmap = enemy_boss1;
		switch (mLevel) {
		case Constants.LEVEL_2:
			type = Constants.ENEMY_TYPE_BOSS2;
			life = Constants.LIFE_BOSS2;
			bitmap = enemy_boss2;
			break;
		case Constants.LEVEL_3:
			type = Constants.ENEMY_TYPE_BOSS3;
			life = Constants.LIFE_BOSS3;
			bitmap = enemy_boss3;
			break;
		}
		mEnemies.add(new Enemy(this, mScreenWidth / 2, -bitmap.getHeight() / 2,
				type, Constants.BOSS_SPEED, life, mPlayer));
	}

	// 为敌方增加子弹到list中
	public void addEnemyBullet(Bullet bullet) {
		mEnemyBullets.add(bullet);
	}

	// 为我方增加子弹到list中
	public void addPlayerBullet(Bullet bullet) {
		mPlayerBullets.add(bullet);
	}

	// 我方进行射击
	public void playerFire() {
		mPlayer.fire();
	}

	// 敌方进行射击
	public void enemyFire(Enemy enemy) {
		if (mRandom.nextBoolean()) {
			enemy.fire();
		}

	}

	/**
	 * 传入爆炸角色（主要获取坐标），添加宝物道具 随机生成
	 * 
	 * @param baseRole
	 */
	public void addProperty(BaseRole baseRole) {
		int type = Constants.ADD_BULLET;
		switch (mRandom.nextInt(10)) {
		case 0:
		case 9:
			type = Constants.ADD_LIFE;
			break;
		case 1:
		case 8:
			type = Constants.CHANGE_BULLET;
			break;
		case 2:
		case 7:
			type = Constants.SPEED_UP;
			break;
		case 3:
			type = Constants.CLEAR_ALL_ENEMY;
			break;
		}
		mProperties.add(new Property(this, baseRole.getX(), baseRole.getY(),
				Constants.DIR_DOWN, type, Constants.PROPERTY_SPEED));

	}

	/**
	 * 清除所有子弹，以及敌机
	 */
	public void clearAll() {
		startAnimation();
		mEnemyBullets.clear();
		for (int i = 0; i < mEnemies.size(); i++) {
			Enemy enemy = mEnemies.get(i);
			addExplode(new Explode(this, enemy));
			enemy = null;
		}
		mEnemies.clear();
	}

	/**
	 * 根据子弹的类型，返回子弹的bitmap
	 * 
	 * @param bulletType
	 * @return bitmap 子弹
	 */
	public Bitmap getBitmapByBulletType(int bulletType) {
		Bitmap temp = null;
		switch (bulletType) {
		case Constants.PLAYER_BULLET_1:
			temp = playerBullet1;
			break;
		case Constants.PLAYER_BULLET_2:
			temp = playerBullet2;
			break;

		case Constants.ENEMY_BULLET_1:
			temp = enemyBullet1;
			break;
		case Constants.ENEMY_BULLET_2:
			temp = enemyBullet2;
			break;
		}
		return temp;
	}

	/**
	 * boss 被杀时候回调
	 */
	@Override
	public void onBossKilled() {
		SoundManager.getInstance(mGameActivity).playSound(
				Constants.SOUND_KEY_BOSS_EXPLODE);

		isBossKilled = true;

		// 游戏胜利时候，提交分数
		if (++mLevel > Constants.LEVEL_3) {
			reportScore();
		}
		// 处理杀死BOSS后文字显示
		new Timer().schedule(new TimerTask() {

			@Override
			public void run() {
				isBossKilled = false;
			}
		}, 3000);

	}

	// 玩家被杀
	public void onPlayerBeKilled() {
		mPlayer.setAlive(false);
		addExplode(new Explode(this, mPlayer));
		SoundManager.getInstance(mGameActivity).playSound(
				Constants.SOUND_KEY_PLAYER_EXPLODE);
		reportScore();
	}

	// 被敌方击中回调处理
	@Override
	public void onPlayerBeFired() {
		// 震动
		vibrator.vibrate(200);
		if (--mPlayer.life < 1) {
			onPlayerBeKilled();
		}
	}

	// 开启动画
	private void startAnimation() {
		startAnimation = true;
	}

	// 画动画,清除敌人和子弹时候调用
	private void drawAnimation(Canvas canvas, Bitmap bitmap) {
		canvas.drawBitmap(bitmap, (mScreenWidth - bitmap.getWidth()) / 2,
				(mScreenHeight - bitmap.getHeight()) / 2, mPaint);
	}

	// 显示提交分数页面
	private void reportScore() {

		Timer timer = new Timer();
		TimerTask timerTask = new TimerTask() {

			@Override
			public void run() {
				Intent intent = new Intent(getContext(),
						ReportScoreActivity.class);
				intent.putExtra(Constants.EXTRA_KEY_SCORE, score);
				getContext().startActivity(intent);
				mGameActivity.finish();
			}
		};
		timer.schedule(timerTask, 3000);

	}

	// 暂停/继续游戏,主要操作控制线程中的isOnPause变量
	public void gameOnPause(boolean isOnPause) {
		mControlThread.isOnPause = isOnPause;
	}

}
